package com.bacel.nb.product.web.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.bacel.nb.product.web.util.WebUtilify;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * Created by wangwei on 16/10/25.
 */
public class PrivilegeFilter implements Filter {

    private static final String EXCLUDE_PATHS = "ExcludePaths"; //过滤列表

    private String privilegeUrl;
    private String unauthUrl;
    private String excludeSource;
    private String noauthModuleUrls;
    private Boolean skinAuth;

    /**
     * 添加属性，这里用来存放不过滤地址正则表达式，可以根据自己需求定制---1
     */
    private String strExcludeFile;
    private String[] arrExcludeFile = null;

    public PrivilegeFilter() {
        setStrExcludeFile("");

    }

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        privilegeUrl = filterConfig.getInitParameter("privilegeUrl");
        unauthUrl = filterConfig.getInitParameter("unauthUrl");
        excludeSource = filterConfig.getInitParameter("excludeSource");
        noauthModuleUrls = filterConfig.getInitParameter("noauthModuleUrls");
        skinAuth = Boolean.parseBoolean(filterConfig.getInitParameter("skinAuth"));

        //设置过滤url
        String tmpExcludeFile = filterConfig.getInitParameter(EXCLUDE_PATHS);
        if (null != tmpExcludeFile) {
            this.setStrExcludeFile(filterConfig.getInitParameter(EXCLUDE_PATHS));
        }

        if (strExcludeFile != null && strExcludeFile.trim().length() > 0) {
            arrExcludeFile = strExcludeFile.split(";");
        }
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String contextPath = httpRequest.getContextPath();
        String servletPath = httpRequest.getServletPath();
//        if (skinAuth || this.checkExclude(servletPath)) {
//            chain.doFilter(request, response);
//            return;
//        }

        //excludeFile 跳出filter
        String requestStr = httpRequest.getRequestURL().toString();
//        if (this.checkExcludeUrl(requestStr)) {
//            chain.doFilter(request,response);
//            return;
//        }
        //GetVerifyimg
        if (!servletPath.startsWith("/assets/") && !servletPath.startsWith("/api/")
                && !servletPath.startsWith("/sysmanage/appdata")&& !servletPath.equals("/sysmanage/login") && !servletPath.equals("/sysmanage/GetVerifyimg") && !servletPath.equals("/sysmanage/userlogin")) {
            HttpSession session = httpRequest.getSession();
            Object pObj = session.getAttribute(WebUtilify.LoginUserKey);
            if (pObj == null) {
                httpResponse.sendRedirect("/sysmanage/login");
                return;
            }
        }

//        ListGageModule datamodule = WebUtilify.GetDataModuleAll();
//        List<sysmoduleDto> list = new ArrayList<>();
//        JSONArray ja = JSONArray.parseArray(JSON.toJSONString(datamodule.getList()));
//        list = JSON.parseArray(ja.toJSONString(), sysmoduleDto.class);
//        sysmoduleDto module = new sysmoduleDto();
//        module.setId(1);
//        module = WebUtilify.setChildren(list, module);
//        module.setName("顶级");
//        List<sysmoduleDto> relist = WebUtilify.getListChildren(module, 0);


        //List<String> privileges = null;
        //privileges = this.initPrivileges(httpRequest);
        //session.setAttribute("privileges", privileges);
        /*
        List<String> privileges = null;
        Object pObj = session.getAttribute("privileges");
        if(pObj == null) {
            privileges = this.initPrivileges(httpRequest);
            if (privileges == null) {
                String redirectUrl = contextPath + unauthUrl;
                httpResponse.sendRedirect(redirectUrl);
                return;
            }
            session.setAttribute("privileges", privileges);
        } else {
            privileges = (List<String>)pObj;
        }

        String pUrl = httpRequest.getServletPath();
        if(!privileges.contains(pUrl)) {
            String redirectUrl = contextPath + unauthUrl;
            httpResponse.sendRedirect(redirectUrl);
            return;
        }
        */

        chain.doFilter(request, response);
    }

    /**
     * @param request 请求
     * @return 列表
     */
    private List<String> initPrivileges(final HttpServletRequest request) {
        AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
        //if (null == principal) {
        //    return null;
        //}

        String ticket = principal.getProxyTicketFor(privilegeUrl);
        String ret = postData(this.privilegeUrl + "&ticket=" + ticket, new ArrayList<>());

        ArrayList<String> privileges = new ArrayList<>();
        JSONArray list = JSON.parseArray(ret);
        if (list != null) {
            for (int i = 0; i < list.size(); i++) {
                JSONObject obj = list.getJSONObject(i);
                String pr = obj.getString("url").trim();
                if (pr.compareTo("/position/list") == 0) {
                    privileges.add("/filter/product_list");
                } else if (pr.compareTo("/version/list") == 0) {
                    privileges.add("/filter/product_list");
                } else if (pr.compareTo("/channel/list") == 0) {
                    privileges.add("/filter/product_list");
                    privileges.add("/filter/version_list");
                } else if (pr.compareTo("/client_config/edit") == 0) {
                    privileges.add("/client_config/start");
                    privileges.add("/client_config/stop");
                }
                privileges.add(obj.getString("url").trim());
            }
            //

            if (this.noauthModuleUrls != null && !this.noauthModuleUrls.isEmpty()) {
                String[] mArr = this.noauthModuleUrls.split(";");
                for (int i = 0; i < mArr.length; i++) {
                    privileges.add(mArr[i].trim());
                }
            }
        }
        return privileges;
    }

    /**
     * @param servletPath 地址
     * @return 结果
     */
    private boolean checkExclude(final String servletPath) {
        boolean ret = false;
        if (excludeSource != null && !excludeSource.isEmpty()) {
            String[] excludeArr = excludeSource.split(";");
            for (int i = 0; i < excludeArr.length; i++) {
                if (servletPath.startsWith(excludeArr[i])) {
                    ret = true;
                    break;
                }
            }
        }
        return ret;
    }

    private boolean checkExcludeUrl(final String requestStr) {
        boolean ret = false;

        PathMatcher matcher = new AntPathMatcher();
        if (arrExcludeFile != null) {
            for (String excludePath : arrExcludeFile) {
                ret = matcher.match(excludePath, requestStr);
                if (!ret) {
                    ret = requestStr.indexOf(excludePath) > 0;
                }
                if (ret) {
                    break;
                }
            }
        }
        return ret;
    }

    @Override
    public void destroy() {

    }


    /**
     * 从用户系统请求数据
     *
     * @param url        URL
     * @param parameters 参数
     * @return 结果字符串
     */
    private static String postData(final String url, final List<BasicNameValuePair> parameters) {
        String result = null;

        try {
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            CloseableHttpClient client = httpClientBuilder.build();

            HttpPost post = new HttpPost(url);
            HttpEntity httpEntity = new UrlEncodedFormEntity(parameters, "utf-8");
            post.setEntity(httpEntity);

            HttpResponse response = client.execute(post);
            HttpEntity resultEntity = response.getEntity();

            result = EntityUtils.toString(resultEntity, "utf-8");
            client.close();
            System.out.println("PostHelper receiveData: " + result);

        } catch (Exception ex) {
            // 单元测试代码，不处理
            ex.printStackTrace();
        }

        return result;
    }

    public void setStrExcludeFile(String strExcludeFile) {
        this.strExcludeFile = strExcludeFile;
    }
}
